# Purpose: Defines the shared context object for the server lifespan and a helper to access it.
# Changes:
# - Removed the faulty `TypeVar` fallback for Context. Relies solely on the SDK import.
# - Added a critical log/raise if Context cannot be imported.

import logging
from dataclasses import dataclass, field
# Make sure Optional is imported
from typing import Any, Dict, Optional

# Import Context type from MCP SDK package
# *** Assuming the correct path is 'mcp.server.fastmcp'. Adjust if your SDK differs. ***
try:
    from mcp.server.fastmcp import Context
except ImportError as e:
    # Log critical error and re-raise if Context cannot be imported.
    # This is better than using an invalid TypeVar.
    logging.critical(
        "FATAL: Could not import Context from mcp.server.fastmcp. "
        "Ensure the MCP SDK is installed correctly and the import path is valid.",
        exc_info=True
    )
    # Re-raise to prevent application from starting incorrectly
    raise ImportError("Failed to import required MCP Context type.") from e

# Use core logger setup
from ..core.logging_setup import get_logger
logger = get_logger(__name__)

@dataclass
class ServerContext:
    """
    Holds shared resources and configurations available during the server's lifespan.
    Instantiated within `app_lifespan` and attached to the MCP context.
    """
    app_config: Dict[str, Any] = field(default_factory=dict)
    # Add other shared resources initialized during lifespan if needed, e.g.:
    # db_pool: Optional[Any] = None

    def get_skill_config(self, skill_name: str) -> Dict[str, Any]:
        """Helper method to safely retrieve skill-specific configuration."""
        skills_config = self.app_config.get("skills")
        if isinstance(skills_config, dict):
             return skills_config.get(skill_name, {})
        return {}


def get_server_context(ctx: Context) -> ServerContext:
    """
    Safely retrieves the application's ServerContext from the MCP request context.

    Args:
        ctx: The MCP Context object provided to tool/resource handlers.

    Returns:
        The ServerContext instance.

    Raises:
        RuntimeError: If the ServerContext is not found (indicates a setup issue).
    """
    # Check attributes robustly
    request_context = getattr(ctx, 'request_context', None)
    if request_context:
         lifespan_ctx = getattr(request_context, 'lifespan_context', None)
         if isinstance(lifespan_ctx, ServerContext):
             return lifespan_ctx
         elif lifespan_ctx is not None:
             actual_type = type(lifespan_ctx).__name__
             logger.error(f"Lifespan context is not ServerContext (Type: {actual_type}). Check lifespan yield.")
             raise RuntimeError("Internal Server Error: Invalid server context type.")
         else:
              logger.error("ServerContext not found within MCP request_context (lifespan_context is None).")
              raise RuntimeError("Internal Server Error: Server context not attached.")
    else:
        # Check if ctx itself might be the ServerContext (less common pattern, but possible)
        if isinstance(ctx, ServerContext):
             logger.warning("Accessing ServerContext directly from ctx object, not via request_context.lifespan_context.")
             return ctx

        logger.error("ServerContext not found in MCP context (request_context missing or None).")
        raise RuntimeError("Internal Server Error: Server context unavailable.")